package com.sky.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.sky.dto.GoodsSalesDTO;
import com.sky.mapper.ReportMapper;
import com.sky.service.ReportService;
import com.sky.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Select;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class ReportServiceImpl implements ReportService {


    @Autowired
    public ReportMapper reportMapper;


    //营业额统计
    @Override
    public TurnoverReportVO turnoverStatistics(LocalDate begin, LocalDate end) {
        //1. 根据传入的begin和end,构建一个日期集合
        List<LocalDate> dateList = getDateList(begin, end);
        //2. 准备数据变量
        List turnoverList = new ArrayList();//营业额集合
        //3. 凑数据->遍历日期集合,拿到每一个日期
        dateList.stream().forEach(date -> {
            Double amount = reportMapper.sumOrderAmountByStatusAndDate(5, date);
            turnoverList.add(amount);//为每一个日期,添加对应的营业额
        });
        //4. 组装返回结果
        TurnoverReportVO vo = TurnoverReportVO.builder()
                .dateList(CollUtil.join(dateList, ","))//hutool的工具类,2024-02-26,2024-02-27,2024-02-28,2024-02-29
                .turnoverList(CollectionUtil.join(turnoverList, ","))
                .build();
        return vo;
    }

    // 用户统计
    @Override
    public UserReportVO userStatistics(LocalDate begin, LocalDate end) {
        //1. 根据传入的begin和end,构建一个日期集合
        List<LocalDate> dateList = getDateList(begin, end);
        //2. 准备数据变量
        List totalUserList = new ArrayList();//总用户数
        List newUserList = new ArrayList();//新增用户数
        //3. 凑数据->遍历日期集合,拿到每一个日期
        dateList.stream().forEach(date -> {
            Integer total = reportMapper.countUserByDate(date);//每天总用户数
            Integer newUsers = reportMapper.countUserByDate(date);//每天新增用户数
            totalUserList.add(total);//添加当天总用户数到集合
            newUserList.add(newUsers);//添加当天新增用户数到集合
        });
        UserReportVO vo = UserReportVO.builder()
                .dateList(CollUtil.join(dateList, ","))//hutool的工具类,2024-02-26,2024-02-27,2024-02-28,2024-02-29
                .totalUserList(CollectionUtil.join(totalUserList, ","))
                .newUserList(CollectionUtil.join(newUserList, ","))
                .build();
        return vo;

    }

    //订单统计
    @Override
    public OrderReportVO ordersStatistics(LocalDate begin, LocalDate end) {
        //1. 根据传入的begin和end,构建一个日期集合
        List<LocalDate> dateList = getDateList(begin, end);
        //2. 准备数据变量
        List orderCountList = new ArrayList();//总订单数列表
        List validOrderCountList = new ArrayList();//有效订单数列表
        Integer totalOrderCount = 0;//总订单数计数器
        Integer validOrderCount = 0;//有效订单数计数器

        //3. 凑数据->遍历日期集合,拿到每一个日期
        for (LocalDate date : dateList) {//不能用stream流,因为要累加
            Integer orderCount = reportMapper.countOrderByStatusAndDate(null, date);//订单数
            Integer vOrderCount = reportMapper.countOrderByStatusAndDate(5, date);//有效订单数
            orderCountList.add(orderCount);//添加订单数到集合
            totalOrderCount += orderCount;//累加订单数
            validOrderCountList.add(validOrderCount);//添加有效订单数到集合
            validOrderCount += vOrderCount;//累加有效订单数
        }
        //4. 计算订单完成率(订单完成率 = 累计有效订单量 / 累计订单量 * 100%)
        Double orderCompletionRate = 0.0;
        if (validOrderCount > 0 && totalOrderCount > 0) {
            orderCompletionRate = validOrderCount * 1.0 / totalOrderCount;//如果都为0,则会出现数学异常
        }
        //5. 组装返回结果
        OrderReportVO vo = OrderReportVO.builder()
                .dateList(CollUtil.join(dateList, ","))//hutool的工具类,2024-02-26,2024-02-27,2024-02-28,2024-02-29
                .orderCountList(CollectionUtil.join(orderCountList, ","))//订单数列表
                .validOrderCountList(CollectionUtil.join(validOrderCountList, ","))//有效订单数列表
                .totalOrderCount(totalOrderCount)//总订单数
                .validOrderCount(validOrderCount)//有效订单数
                .orderCompletionRate(orderCompletionRate)//订单完成率
                .build();
        return vo;
    }

    //销量排名Top10
    @Override
    public SalesTop10ReportVO top10(LocalDate begin, LocalDate end) {
        //1.准备数据变量
        List<String> nameList = new ArrayList();//商品名称列表
        List<Integer> numberList = new ArrayList();//销量列表
        //2. 凑数据->调用mapper接口,拿到数据
        List<GoodsSalesDTO> list = reportMapper.top10(begin, end);
        list.stream().forEach(goodsSalesDTO -> {
            nameList.add(goodsSalesDTO.getName());//添加商品名称到集合
            numberList.add(goodsSalesDTO.getNumber());//添加销量到集合
        });
        SalesTop10ReportVO vo = SalesTop10ReportVO.builder()
                .nameList(CollectionUtil.join(nameList, ","))
                .numberList(CollectionUtil.join(numberList, ","))
                .build();
        return vo;
    }

    //今日数据
    @Override
    public BusinessDataVO businessData(LocalDate today) {
        /*//1.获取今日时间
        LocalDate today = LocalDate.now();//为了service复用报表导出*/
        //2. 凑数据->调用mapper接口,拿到数据
        Double turnover = reportMapper.sumOrderAmountByStatusAndDate(5, today);//营业额
        Integer validOrderCount = reportMapper.countOrderByStatusAndDate(5, today);//有效订单数
        Integer totalOrderCount = reportMapper.countOrderByStatusAndDate(null, today);//总订单数
        Integer newUsers = reportMapper.countUserByDate(today);//新增用户数

        //订单完成率(订单完成率：有效订单数 / 总订单数 )
        Double orderCompletionRate = 0.0;
        if (validOrderCount > 0 && totalOrderCount > 0) {
            orderCompletionRate = validOrderCount * 1.0 / totalOrderCount;//如果都为0,则会出现数学异常
        }
        //平均客单价(平均客单价：营业额 / 有效订单数)
        Double unitPrice = 0.0;
        if (totalOrderCount > 0) {
            unitPrice = turnover * 1.0 / totalOrderCount;
        }
        BusinessDataVO vo = BusinessDataVO.builder()
                .validOrderCount(validOrderCount)//有效订单数
                .newUsers(newUsers)//新增用户数
                .date(today)//日期
                .turnover(turnover)//营业额
                .unitPrice(unitPrice)//客单价
                .orderCompletionRate(orderCompletionRate)//订单完成率
                .build();
        return vo;
    }

    //今日订单
    @Override
    public OrderOverViewVO overviewOrders() {
        //1.获取今日时间
        LocalDate today = LocalDate.now();
        //2. 凑数据->调用mapper接口,拿到数据
        Integer waitingOrders = reportMapper.countOrderByStatusAndDate(2, today);//待接单数量：状态为2
        Integer deliveredOrders = reportMapper.countOrderByStatusAndDate(3, today);//待派送数量：状态为3
        Integer completedOrders = reportMapper.countOrderByStatusAndDate(5, today);//已完成数量：状态为5
        Integer cancelledOrders = reportMapper.countOrderByStatusAndDate(6, today);//已取消数量：状态为6
        Integer allOrders = reportMapper.countOrderByStatusAndDate(null, today);//总订单数
        //3.组装返回结果
        OrderOverViewVO vo = OrderOverViewVO.builder()
                .waitingOrders(waitingOrders)//待接单数量
                .deliveredOrders(deliveredOrders)//待派送数量
                .completedOrders(completedOrders)//已完成数量
                .cancelledOrders(cancelledOrders)//已取消数量
                .allOrders(allOrders)//总订单数
                .build();
        return vo;
    }

    //查询套餐总览
    @Override
    public SetmealOverViewVO countSetmealByStatus() {
        //查询套餐总览
        Integer start = reportMapper.countSetmealByStatus(1);//套餐起售状态
        Integer stop = reportMapper.countSetmealByStatus(0);//菜品停售状态
        SetmealOverViewVO vo = SetmealOverViewVO.builder()
                .sold(start)//套餐起售状态
                .discontinued(stop)//菜品停售状态
                .build();
        return vo;
    }

    //查询菜品总览
    @Override
    public DishOverViewVO countDishByStatus() {
        Integer start = reportMapper.countDishByStatus(1);//套餐起售状态
        Integer stop = reportMapper.countDishByStatus(0);//菜品停售状态
        DishOverViewVO vo = DishOverViewVO.builder()
                .sold(start)//套餐起售状态
                .discontinued(stop)//菜品停售状态
                .build();
        return vo;
    }

   //查看菜品和套餐的起售停售状态,${}和#{}搭配使用
    @Override
    public CoutSetmealAndDishByStatus countDishAndSetmealByStatus() {
        //判断是不是菜品
        CoutSetmealAndDishByStatus cs = new CoutSetmealAndDishByStatus();
        //查询菜品的起售停售状态
        Integer startDish = reportMapper.countDishAndSetmealByStatus("dish", 1);//菜品起售
        Integer stopDish = reportMapper.countDishAndSetmealByStatus("dish", 0);//菜品停售
        //查看套餐的起售状态
        Integer startSetmeal = reportMapper.countDishAndSetmealByStatus("setmeal", 1);//套餐起售
        Integer stopSetmeal = reportMapper.countDishAndSetmealByStatus("setmeal", 0);//套餐停售
        cs.setDiscontinuedDish(stopDish);//菜品停售
        cs.setSoldDish(startDish);//菜品起售
        cs.setDiscontinuedSetmeal(stopSetmeal);//套餐停售
        cs.setSoldSetmeal(startSetmeal);//套餐起售
        return cs;
    }


    //根据开始和结束日期活动日期列表(抽取的方法)
    private List<LocalDate> getDateList(LocalDate begin, LocalDate end) {
        List<LocalDate> dateList = new ArrayList<>();
        LocalDate dateIndex = begin;//日期指针

        while (!dateIndex.isAfter(end)) {
            dateList.add(dateIndex);
            dateIndex = dateIndex.plusDays(1);//指针后移1天
        }

        log.info("得到的日期集合:{}", dateList);
        return dateList;
    }
}





